1. Field of the Invention
The present invention relates generally to an improved data processing system and, in particular, to the compilation of computer-usable program code. Still more particularly, the present invention relates to use of name mangling techniques to encode cross procedure register assignment.
2. Description of the Related Art
Compilers are software programs used to translate program instructions written in a source language to equivalent program instructions written in a target language. The source language is usually a high-level language designed to be interpreted by humans; the target language is usually a low-level language suitable for execution by computer hardware. In this common case, the compiler is said to compile the source code into executable code.
Different kinds of compilers can perform different functions. For example, optimizing compilers are used to improve the quality of the program instruction generated without changing the intended meaning of the source code. For example, an optimizing compiler can reduce the time required to execute the program instructions or the memory footprint of the resulting program. During the optimization process, the source code is often re-ordered so that commands are executed more efficiently.
Many programs to be optimized can typically be characterized as sets of procedures, functions, or possibly methods, hereafter referred to as “functions.” Each function is intended to perform some particular task towards the overall goal of the program as a whole. Each program comprises one or more related functions. For example, a program can have the goal of comparing home prices in Texas at different times to home prices in California at one selected time. One function may be to calculate the averages of home prices in Texas at different times and a second function may be to calculate the average price of homes in California at the selected time. A third function may be to calculate the average of home prices in Texas at a given time relative to the home prices in California at the specified time. This third function might be iterated until all comparisons are made of each time for Texas homes relative to the one selected time for California homes.
Each of these three functions may include calls to one or more functions to accomplish these tasks. For example, a function would calculate the mathematical average of a set of numbers, which in this case would be a set of home prices in the relevant state.
Continuing this example, a programmer desires to optimize this overall program using an optimizing compiler. Much freedom exists to perform transformations within each of the three individual functions. When optimizing transformations are applied within a given function, such an optimizing transformation is known as an intraprocedural optimization. However, additional optimization can be achieved by performing a technique known as interprocedural analysis.
Interprocedural analysis is a compiler technique used to improve performance in programs containing frequently used functions, where the analysis spans the scope of more than one function. In the above example, calculation of the price of homes in California only needs to be performed once for the one selected time. While this value can be calculated each time the price of homes in Texas is calculated at a particular time, such additional calculation is wasteful. Instead, the average price of homes for the one selected California time can be calculated once, stored, and then referenced by the third function that performs the comparison between home prices between Texas and California homes. Interprocedural analysis can detect this potential optimization. Thereafter, interprocedural optimization can be used to modify the program to take advantage of this optimization.
Whether or not the program is complex, interprocedural optimization can sometimes lead to transformation and optimization across function boundaries. However, in computer programming, such transformations are often limited by calling conventions imposed by the computer's operating system.
A calling convention is a standardized method for a program to pass parameters to a function, and receive a result value back from that function. Many different calling conventions exist. Calling conventions indicate the roles of all registers of the computer's central processing unit. A register is an atomic memory element within the central processing unit. Some registers are indicated as “callee save,” whereas other registers are indicated as “caller save.” A specific subset of registers is also indicated for purposes of parameter passing.
In the above example program, restrictions imposed by the calling conventions of the computer's operating system could prevent implementation of the identified optimization of storing the average price of California homes at the one selected time in a register, as generated by the first function, and then referencing that value directly from the register the next time the third function is to use that value (as opposed to recalculating the average price of California homes at the selected time or loading a value from main memory). Thus, the goal of optimizing the program can be thwarted by the requirements of calling conventions.
In some cases, this limitation can be overcome by deliberately breaking the calling conventions. However, breaking calling conventions must be done with great care, and only on internally visible functions or when performing a whole program compilation. Additionally, use of other optimizing tools must be relinquished in favor of using the technique of breaking the calling conventions. For example, code instrumenting tools, debugging tools, and post compilation object code optimizers cannot be used because these tools fundamentally rely on calling conventions. Thus, the goal of fully optimizing the program is again thwarted.